<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <!-- <button id="btn">点击抽奖</button>

    <script>
        //生成随机数
        function rand(m, n) {
            return Math.ceil(Math.random() * (n - m + 1)) + m - 1;
        }

        const btn = document.querySelector('#btn');
        btn.addEventListener('click', function () {
            const p = new Promise((resolve, reject) => {
                setTimeout(() => {
                    let n = rand(1, 100);
                    if (n <= 30) {
                        resolve(n); // 将 promise 对象状态设置为成功
                    } else {
                        reject(n);// 将 promise 对象状态设置为失败
                    }
                }, 1000);
            });
            p.then((value) => {
                alert("恭喜你中奖了！您的中奖数字为" + value)
            }, (reason) => {
                alert("很遗憾你没有中奖,您的号码为" + reason)
            });
        });
    </script> -->

    <script>
        class Promise {
            // 构造方法
            constructor(executor) {
                // 4.添加属性
                this.PromiseState = 'pending';
                this.PromiseResult = null;

                // 12.声明一个回调属性
                this.callbacks = [];

                // 7.修正this指向
                const self = this;

                // 5.resolve函数
                function resolve(data) {

                    // 9.判断是否已经发生过状态改变
                    if (self.PromiseState !== 'pending') return;

                    // 修改对象的状态 (promiseState)
                    self.PromiseState = 'fulfiled';
                    // 设置对象结果值 (promiseResult)
                    self.PromiseResult = data;

                    // 12.调用成功的回调函数
                    setTimeout(() => {
                        self.callbacks.forEach(item => {
                            item.onResolved(data)
                        })
                    });
                }

                // 6.reject函数
                function reject(data) {

                    // 9.判断是否已经发生过状态改变
                    if (self.PromiseState !== 'pending') return;

                    // 修改对象的状态 (promiseState)
                    self.PromiseState = 'rejected';
                    // 设置对象结果值 (promiseResult)
                    self.PromiseResult = data;

                    // 12.调用失败的回调函数
                    setTimeout(() => {
                        self.callbacks.forEach(item => {
                            item.onRejected(data)
                        })
                    });
                }

                // 7.try catch 接收 throw (抛出)错误
                try {

                    // 3.同步调用 (执行器函数)
                    executor(resolve, reject);
                } catch (e) {

                    // 8.修改Promise对象状态为失败
                    reject(e);
                }
            }

            // then方法封装
            then(onResolved, onRejected) {
                const self = this;
                // 判断回调函数参数
                if (typeof onRejected !== 'function') {
                    onRejected = reason => {
                        throw reason;
                    }
                }
                if (typeof onResolved !== 'function') {
                    onResolved = value => {
                        return value;
                    }
                }
                return new Promise((resolve, reject) => {
                    // 封装函数
                    function callback(type) {
                        try {
                            // 获取回调函数的指向结果
                            let result = type(self.PromiseResult);
                            // 判断
                            if (result instanceof Promise) {
                                // 如果是 Promise 类型的对象
                                result.then(v => {
                                    resolve(v);
                                }, r => {
                                    reject(r);
                                })
                            } else {
                                // 结果的对象状态为成功
                                resolve(result);
                            }
                        } catch (e) {
                            reject(e);
                        }
                    }
                    // 10.调用回调函数
                    if (this.PromiseState === 'fulfiled') {
                        setTimeout(() => {
                            callback(onResolved);
                        });
                    }

                    if (this.PromiseState === 'rejected') {
                        setTimeout(() => {
                            callback(onRejected);
                        });
                    }

                    // 11.如果为异步任务  判断pending状态
                    if (this.PromiseState === 'pending') {
                        // 保存回调函数
                        this.callbacks.push({
                            onResolved: function () {
                                callback(onResolved);
                            },
                            onRejected: function () {
                                callback(onRejected);
                            }
                        })
                    }
                })
            }

            // catch方法
            catch(onRejected) {
                return this.then(undefined, onRejected);
            }

            // resolve方法
            static resolve(value) {
                // 返回promise对象
                return new Promise((resolve, reject) => {
                    if (value instanceof Promise) {
                        value.then(v => {
                            resolve(v)
                        }, r => {
                            reject(r);
                        })
                    } else {
                        // 状态设置为成功
                        resolve(value)
                    }
                });
            }

            // reject方法
            static reject(reason) {
                return new Promise((resolve, reject) => {
                    reject(reason);
                })
            }

            // all方法
            static all(promises) {
                // 返回结果为promise对象
                return new Promise((resolve, reject) => {
                    // 声明变量
                    let count = 0;
                    let arr = [];
                    // 遍历
                    for (let i = 0; i < promises.length; i++) {
                        promises[i].then(v => {
                            // 如果进入这里，表明对象的状态是成功的
                            // 所有promise对象都成功 才能将放回的promise设置为成功
                            count++;
                            // 将当前promise对象成功的结果存入数组中
                            arr[i] = v;
                            if (count === promises.length) {
                                resolve(arr);
                            }
                        }, r => {
                            reject(r);
                        })
                    }
                })
            }

            // race方法
            static race(promises) {
                return new Promise((resolve, reject) => {
                    for (let i = 0; i < promises.length; i++) {
                        promises[i].then(v => {
                            // 改变返回对象的状态为成功
                            resolve(v);
                        }, r => {
                            // 修改返回对象的状态为失败
                            reject(r);
                        })
                    }
                })
            }
        }













        let p = new Promise((resolve, reject) => {
            resolve('ok');
        });

        p.then(value => {
            console.log(value);
        }, reason => {
            console.log(reason);
        })
    </script>
</body>

</html>